﻿using System;
using System.Text;
using System.Net.Sockets;
using System.IO;
using UnityEngine;

class SocketClient
{
    string ip = "127.0.0.1";
    int port = 8500;

    TcpClient client;
    NetworkStream stream;

    MemoryStream mem;//缓存流
    BinaryReader reader;//缓存流的读取器

    const int BufferSize = 8192;
    byte[] buffer = new byte[BufferSize];

    public SocketClient()
    {
        client = new TcpClient();
        client.BeginConnect(ip, port, OnConnect, null);
    }

    void OnConnect(IAsyncResult ar)
    {
        Debug.Log("连接上服务器:" + client.Client.RemoteEndPoint);
        stream = client.GetStream();//获取网络流
        mem = new MemoryStream();
        reader = new BinaryReader(mem);


        //开启异步读取数据
        stream.BeginRead(buffer, 0, BufferSize, Read, null);
    }

    //子线程读取消息
    void Read(IAsyncResult ar)
    {
        try
        {
            int readCount = stream.EndRead(ar);
            if (readCount == 0) throw new Exception("读取异常");

            //接收，并把消息抛给逻辑层
            OnReceive(buffer, readCount);

            lock (client)
            {
                Array.Clear(buffer, 0, BufferSize);
                stream.BeginRead(buffer, 0, BufferSize, Read, null);
            }
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
            OnDisconnect();
        }
    }
    void OnReceive(byte[] bytes, int count)
    {
        mem.Seek(0, SeekOrigin.End);//指针指到最后，
        mem.Write(bytes, 0, count);//消息往后追加
        mem.Seek(0, SeekOrigin.Begin);//指针指到开头，开始读消息

        while (RemaindLength() > 4)//判断剩余长度是否够一个int32的长度
        {
            //获取消息长度,指针后移了4位
            int length = reader.ReadInt32();

            if (RemaindLength() >= length)//剩余字节数是否大于消息长度
            {
                byte[] content = reader.ReadBytes(length);
                OnMessage(content);
            }
            else
            {
                mem.Seek(-4, SeekOrigin.Current);//把指针前移4位，保证消息的完整性是[长度+消息]
                break;
            }
        }

        byte[] remain = reader.ReadBytes(RemaindLength());//把剩余的半包读取出来
        mem.SetLength(0);//把缓存流清空，
        mem.Write(remain, 0, remain.Length);//写入剩余的半包
    }
    int RemaindLength()
    {
        return (int)(mem.Length - mem.Position);
    }
    //往流里面写入==给服务器发消息
    //void Write(byte[] content)
    //{
    //    //获取消息和消息长度
    //    byte[] length = BitConverter.GetBytes(content.Length);

    //    //使用内存流做缓存，拼接遵循 [长度+消息]协议 的消息
    //    MemoryStream mem = new MemoryStream();
    //    mem.Write(length, 0, 4);
    //    mem.Write(content, 0, content.Length);

    //    //把最终消息发送出去
    //    byte[] bytes = mem.ToArray();
    //    stream.Write(bytes, 0, bytes.Length);
    //}


    //客户端断开连接
    void OnDisconnect()
    {
        stream.Close();//流关闭
        client.Close();//客户端关闭
    }

    void OnWrite(byte[] content)
    {
        try
        {
            ByteBuffer bytebuff = new ByteBuffer();
            bytebuff.WriteInt(content.Length);
            bytebuff.WriteBytes(content);

            byte[] bytes = bytebuff.ToBytes();
            stream.Write(bytes, 0, bytes.Length);
        }
        catch (Exception e)
        {

            Debug.Log(e.ToString());
            throw;
        }
    }


    //接到一条消息
    void OnMessage(byte[] content)
    {
        NetworkManager.Instance.AddEvent(new ByteBuffer(content));
    }

    //向服务器发送消息
    public void Send(byte type, string msg)
    {
        ByteBuffer buf = new ByteBuffer();
        buf.WriteByte(type);
        buf.WriteString(msg);

        OnWrite(buf.ToBytes());

    }
    public void Send(byte type, byte[] content)
    {
        ByteBuffer buf = new ByteBuffer();
        buf.WriteByte(type);
        buf.WriteBytes(content);

        OnWrite(buf.ToBytes());
    }
}